package com.yanfan.energy.quartz;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.serotonin.modbus4j.BatchRead;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.locator.BaseLocator;
import com.yanfan.common.utils.DateUtils;
import com.yanfan.energy.domain.NjEnergyDevice;
import com.yanfan.energy.domain.NjEnergyDeviceData;
import com.yanfan.energy.domain.NjEnergyIp;
import com.yanfan.energy.service.INjEnergyDeviceDataService;
import com.yanfan.energy.service.INjEnergyDeviceService;
import com.yanfan.energy.service.INjEnergyIpService;
import com.yanfan.protocol.utils.Modbus4jUtils;
import com.yanfan.protocol.utils.ModbusOffsetUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Component("njEnergyTask")
public class GetModbusTcpDataJob {
    @Resource
    private INjEnergyDeviceService energyDeviceService;
    @Resource
    private INjEnergyIpService energyIpService;
    @Resource
    private INjEnergyDeviceDataService energyDeviceDataService;


    /**
     * 定时获取能耗数据
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     * @throws ModbusInitException
     */
    public void  GetModbusTcpData() throws ModbusTransportException, ErrorResponseException, ModbusInitException {
        //获取所有采集器的ip
        List<NjEnergyIp> ips = energyIpService.list(null);
        // 处理单独读取结果的列表
        ArrayList<NjEnergyDeviceData> list = new ArrayList<>();
        for (NjEnergyIp ip : ips) {
            ModbusMaster master = Modbus4jUtils.getMaster(ip.getIpAddress(), 502);
            //获取从站id
            List<NjEnergyDevice> devices = energyDeviceService.list(new LambdaQueryWrapper<NjEnergyDevice>()
                    .eq(NjEnergyDevice::getIp, ip.getIpAddress())
                    .orderByAsc(NjEnergyDevice::getSlaveIdCount));

            // 添加要读取的寄存器
            int slaveId = devices.size(); // 从站 ID
            //设备名称
           /* List<String> deviceNames = devices.stream().map(NjEnergyDevice::getDeviceName)
                    .collect(Collectors.toList());*/
            // 定义一个从站 ID 和偏移量的列表
            int dataType = DataType.FOUR_BYTE_FLOAT; // 数据类型

            // 获取寄存器偏移量
            int[] offsets = ModbusOffsetUtils.generateOffsets(slaveId);
            //System.out.println(Arrays.toString(offsets));
            String time = DateUtils.getTime();
            for (int i = 0; i < slaveId; i++) {
                NjEnergyDeviceData energyDeviceData = new NjEnergyDeviceData();
                energyDeviceData.setId(devices.get(i).getDeviceName());
                energyDeviceData.setPosition(ip.getPosition());
                energyDeviceData.setDeviceName(devices.get(i).getDeviceName());
                energyDeviceData.setDeviceType(devices.get(i).getDeviceType());
                energyDeviceData.setIdentifier(devices.get(i).getIdentifier());
                energyDeviceData.setBuilding(devices.get(i).getBuilding());
                energyDeviceData.setUpdateTime(time);

                try {
                    // 单独读取每个寄存器的数据
                    Number value = master.getValue(BaseLocator.holdingRegister(i + 1, offsets[i], dataType));
                    switch (String.valueOf(value)){
                        case "NaN":
                            energyDeviceData.setValue("0.00");
                            break;
                        default:
                            energyDeviceData.setValue(String.valueOf(value));
                            break;
                    }
                } catch (Exception e) {
                    // 单个寄存器读取失败，设置默认值并记录错误
                    //System.out.println("读取设备 " + " 时发生异常：" + e.getMessage());
                    energyDeviceData.setValue("0.00"); // 或者设置为0等默认值
                }

                list.add(energyDeviceData);
            }
            //System.out.println(list);
            //System.out.println("结束==");
        }
        energyDeviceDataService.saveOrUpdateBatch(list);

    }
}
